package com.study.commen.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Environment;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * Status Bar Tint Color Utils
 */

public final class StatusBarUtils {
    private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
    private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
    private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";

    private static final ITintStatusBar sTintStatusBarImpl;

    private StatusBarUtils() {
    }

    static {
        // 根据版本来设置实现
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            sTintStatusBarImpl = new TintStatusBarMImpl();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            sTintStatusBarImpl = new TintStatusBarLollipopImpl();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            sTintStatusBarImpl = new TintStatusBarKitkatImpl();
        } else {
            sTintStatusBarImpl = new ITintStatusBar() {
                @Override
                public void tintColor(@NonNull Window window, int color) {
                    // 空实现
                }
            };
        }
    }

    /**
     * 统一调用着色方法
     */
    public static void tintColor(@NonNull Activity activity, String color, int defaultColor) {
        final Window window = activity.getWindow();
        if (window == null
                || (window.getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) > 0) {
            // 全屏页面不设置
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            final int c = TintUiUtils.parseColor(color, defaultColor);
            sTintStatusBarImpl.tintColor(window, c);
            if (!TintUiUtils.isColorDarker(c)) {
                setStatusBarDarkMode(window);
            }
        }
    }

    public static void tintColor(@NonNull Activity activity, @ColorRes int color) {
        final Window window = activity.getWindow();
        if (window == null
                || (window.getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) > 0) {
            // 全屏页面不设置
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            sTintStatusBarImpl.tintColor(window, ContextCompat.getColor(activity, color));
            setStatusBarDarkMode(window);
        }
    }

    public static int getSystemBarHeight(final Activity context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    /**
     * 设置状态栏的 icon / text 颜色变深
     */
    public static void setStatusBarDarkMode(@NonNull Window window) {
        if (isMIUI()) {
            Class<? extends Window> clazz = window.getClass();
            try {
                Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                int darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                extraFlagField.invoke(window, darkModeFlag, darkModeFlag);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //开发版 7.7.13 及以后版本采用了系统API，旧方法无效但不会报错，所以两个方式都要加上
                    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (isMeizu()) {
            WindowManager.LayoutParams params = window.getAttributes();
            try {
                Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(params);
                value |= bit;
                meizuFlags.setInt(params, value);
                window.setAttributes(params);
                darkFlag.setAccessible(false);
                meizuFlags.setAccessible(false);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    }

    public interface ITintStatusBar {
        void tintColor(@NonNull Window window, @ColorInt int color);
    }

    private static class TintStatusBarMImpl extends TintStatusBarLollipopImpl {
        @TargetApi(23)
        @Override
        public void tintColor(@NonNull Window window, @ColorInt int color) {
            super.tintColor(window, color);
            //TODO 添加 icon 变深颜色

        }
    }

    private static class TintStatusBarLollipopImpl implements ITintStatusBar {
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void tintColor(@NonNull Window window, @ColorInt int color) {
            //取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            //设置状态栏颜色
            window.setStatusBarColor(color);

            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);

            final ViewGroup contentView = window.findViewById(Window.ID_ANDROID_CONTENT);
            final View firstChild = contentView.getChildAt(0);
            if (firstChild != null) {
                ViewCompat.setFitsSystemWindows(firstChild, false);
                ViewCompat.requestApplyInsets(firstChild);
            }
        }
    }

    private static class TintStatusBarKitkatImpl implements ITintStatusBar {
        // 避免重复设置
        private static final String TAG_FAKE_STATUS_BAR_VIEW = "statusBarView";
        private static final String TAG_MARGIN_ADDED = "marginAdded";

        @TargetApi(Build.VERSION_CODES.KITKAT)
        @Override
        public void tintColor(@NonNull Window window, @ColorInt int color) {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

            final ViewGroup contentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
            final View firstChild = contentView.getChildAt(0);

            View statusBarView = window.getDecorView().findViewWithTag(TAG_FAKE_STATUS_BAR_VIEW);
            if (statusBarView != null) {
                ((ViewGroup) window.getDecorView()).removeView(statusBarView);
            }

            statusBarView = new View(window.getContext());
            final int statusBarHeight = getStatusBarHeight(window.getContext());
            final FrameLayout.LayoutParams layoutParams = new FrameLayout
                    .LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight);
            layoutParams.gravity = Gravity.TOP;
            statusBarView.setLayoutParams(layoutParams);
            // 状态栏颜色
            statusBarView.setBackgroundColor(color);
            // 防止重复设置
            statusBarView.setTag(TAG_FAKE_STATUS_BAR_VIEW);
            ((ViewGroup) window.getDecorView()).addView(statusBarView);

            if (firstChild == null) {
                return;
            }

            if (!TAG_MARGIN_ADDED.equals(firstChild.getTag())) {
                FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) firstChild.getLayoutParams();
                lp.topMargin += statusBarHeight;
                firstChild.setLayoutParams(lp);
                firstChild.setTag(TAG_MARGIN_ADDED);
            }

            ViewCompat.setFitsSystemWindows(firstChild, false);
        }
    }

    private static int getStatusBarHeight(Context context) {
        int statusBarHeight = 0;
        final Resources res = context.getResources();
        // 反射获取系统状态栏高度
        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = res.getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

    public static int getStatusBarHeightFixResource(final Context context) {
        final Resources resources = context.getResources();
        final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0)
            return resources.getDimensionPixelSize(resourceId);
        else
            return (int) Math.ceil((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
    }

    /**
     * 判断是否 MIUI
     */
    public static boolean isMIUI() {
        FileInputStream is = null;
        try {
            is = new FileInputStream(new File(Environment.getRootDirectory(), "build.prop"));
            final Properties prop = new Properties();
            prop.load(is);
            return prop.getProperty(KEY_MIUI_VERSION_CODE) != null
                    || prop.getProperty(KEY_MIUI_VERSION_NAME) != null
                    || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE) != null;
        } catch (Exception e) {
            return false;
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    // ignore all exception
                }
            }
        }
    }

    /**
     * 判断魅族 Flyme 系统
     */
    public static boolean isMeizu() {
        return Build.DISPLAY.startsWith("Flyme");
    }

    public static void transparentStatus(Activity activity) {
        //make full transparent statusBar
        if (Build.VERSION.SDK_INT >= 19) {
            WindowManager.LayoutParams params = activity.getWindow().getAttributes();
            params.flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        }
        if (Build.VERSION.SDK_INT >= 21) {
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    }
}
